package com.fingard.dsp.bank.directbank.bfb01;

import java.security.PublicKey;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.crypto.SignVerifyHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISMSRec;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.dsp.bank.reqrespobj.smsrec.ReqSMSRec;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;

/**
 * 邦付宝快捷支付
 */
public class BFB01SMSRec extends BFB01Base implements ISMSRec {
	/**
	 * 1、验证码申请      2、首次绑卡支付      3、协议支付
	 */
	public RetAtsSingle d_9110_SMSRec(ReqSMSRec p_req9110) throws Exception{
		RetAtsSingle retAts = new RetAtsSingle(p_req9110.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9110.singleDetail.recAct, "smsRec");
			if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath)|| !FileHelper.existFile(actItem.oppCertFilePath)) {
				tmpRetDetail.respCode = "0";

				if (actItem == null) {
					tmpRetDetail.respInfo = "未找到账号" + p_req9110.singleDetail.recAct + "对应的商户配置信息";
				} else {
					tmpRetDetail.respInfo = "账号" + p_req9110.singleDetail.recAct + "对应的证书文件不存在";
				}

				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				tmpRetDetail.transAmt = p_req9110.singleDetail.payAmount;

				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}

			// 签名原始数据
			HashMap<String, String> signMap = new HashMap<String, String>();

			// 00:GBK  01:GB2312  02:UTF-8
			signMap.put("charset", "00");
			signMap.put("version", "1.0");
			signMap.put("signType", "RSA");
			signMap.put("merchantId", actItem.merchantId);
			signMap.put("clientIP", actItem.createIP);

			if (!p_req9110.singleDetail.step.equals("03")) {
				if (p_req9110.singleDetail.cardType.equals("2")) {
					// 借记卡
					signMap.put("cardType", "0");
				}
				if (p_req9110.singleDetail.cardType.equals("3")) {
					// 信用卡
					signMap.put("cardType", "1");
				}
				
				signMap.put("cardNo", p_req9110.singleDetail.payAct);
				signMap.put("cardName", p_req9110.singleDetail.payName);
				signMap.put("cardPhone", p_req9110.singleDetail.cellPhone);
				
				signMap.put("idInfo", p_req9110.singleDetail.certNum);
				signMap.put("idType", getBankConfig().getMapValueByKey("RealTimecertType", p_req9110.singleDetail.certType));
			}
			

			if (p_req9110.singleDetail.cvv2.length() > 0 && p_req9110.singleDetail.expiredDate.length() > 0) {
				SimpleDateFormat sdf = new SimpleDateFormat(getBankConfig().getMapValueByKey("exDateFromATS", "0"));
				String expiredDate = sdf.format(sdf.parse(p_req9110.singleDetail.expiredDate));

				signMap.put("expiredDate", expiredDate);
				signMap.put("cvv2", p_req9110.singleDetail.cvv2);
			}
			
			// 用户标识
			signMap.put("identityId", "");

			// 用户标识类型
			signMap.put("identityType", "");

			/*
			 * 步骤，01发短信，02提交短信验证码扣款
			 */
			if (p_req9110.singleDetail.step.equals("01")) {
				signMap.put("service", "ApplyQuickSms");
			} else if (p_req9110.singleDetail.step.equals("02")) {
				signMap.put("service", "FirstQPayment");

				// 商户请求流水号
				signMap.put("mercReqNo", p_req9110.singleDetail.askNumber);

				// 商户订单号
				signMap.put("mercOrdNo", p_req9110.singleDetail.askNumber);

				// 订单时间
				signMap.put("ordDate", Format.Date8Format.format(p_req9110.singleDetail.getPayDateTime()));

				// 敏感信息标识
				signMap.put("encryptFlag", "1");
				signMap.put("totalAmount", StringHelper.amountMultiply100(p_req9110.singleDetail.payAmount));
				signMap.put("currency", convertCurToBank(p_req9110.singleDetail.payCur));

				String productName = p_req9110.singleDetail.purpose;
				if (productName.equals("")) {
					productName = p_req9110.singleDetail.memo;
				}
				if (productName.equals("")) {
					productName = p_req9110.singleDetail.abstractATS;
				}

				// 商品信息
				signMap.put("productId", "");
				signMap.put("productName", productName);
				signMap.put("productDesc", "");

				// 短信验证码
				signMap.put("smsCode", p_req9110.singleDetail.verifyCode);

				// 短信操作码
				signMap.put("smsOpCd", "");

				signMap.put("offlineNotifyUrl", actItem.notifyURL);

				// 是否为协议支付
				signMap.put("isRegAgreement", "Y");

				// 原样返回
				signMap.put("backParam", "");
			} else if (p_req9110.singleDetail.step.equals("03")) {
				signMap.put("service", "AgrPayment");

				// 商户请求流水号
				signMap.put("mercReqNo", p_req9110.singleDetail.askNumber);

				// 商户订单号
				signMap.put("mercOrdNo", p_req9110.singleDetail.askNumber);

				// 订单时间
				signMap.put("ordDate", Format.Date8Format.format(p_req9110.singleDetail.getPayDateTime()));
				
				// 协议号
				signMap.put("agreeNo", p_req9110.singleDetail.authAgNum);

				signMap.put("totalAmount", StringHelper.amountMultiply100(p_req9110.singleDetail.payAmount));
				signMap.put("currency", convertCurToBank(p_req9110.singleDetail.payCur));

				String productName = p_req9110.singleDetail.purpose;
				if (productName.equals("")) {
					productName = p_req9110.singleDetail.memo;
				}
				if (productName.equals("")) {
					productName = p_req9110.singleDetail.abstractATS;
				}

				// 商品信息
				signMap.put("productId", "");
				signMap.put("productName", productName);
				signMap.put("productDesc", "");
				
				// 短信验证码
				signMap.put("smsCode", p_req9110.singleDetail.verifyCode);

				signMap.put("offlineNotifyUrl", actItem.notifyURL);

				// 原样返回
				signMap.put("backParam", "");
			} else {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未能识别的step：" + p_req9110.singleDetail.step;

				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				tmpRetDetail.transAmt = p_req9110.singleDetail.payAmount;

				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}

			// 获取HTTP post请求数据
			String reqStr = getHttpPostStr(signMap, actItem);

			// 发送邦付宝并获取返回
			String tmpStrRet[] = sendQuickPay(reqStr);

			// 解析邦付宝返回
			if (tmpStrRet[0].length() == 0) {
				Map<String, String> respMap = getRet(tmpStrRet[1].replace("\"", ""));

				String respCode = respMap.get("returnCode");

				if (respCode.equals("000000")) {
					// 服务器签名
					String respSign = respMap.get("serverSign");
					WriteBankLogLn2("服务器签名: " + respSign);
					byte[] respSignBytes = hexStringToBytes(respSign);

					// 服务器证书
					String serverCert = respMap.get("serverCert");
					WriteBankLogLn2("服务器证书: " + serverCert);
					PublicKey pubKey = getPublicKey(serverCert);

					// 验签原始串
					String respVerifyStr = getVerifyStr(tmpStrRet[1]);
					WriteBankLogLn2("待验签数据: " + respVerifyStr);

					// 验签
					boolean verifyResult = SignVerifyHelper.verifySign(respVerifyStr.getBytes(getCharset()), respSignBytes, pubKey, "SHA1withRSA");

					// 验签处理
					if (verifyResult == true) {
						if (p_req9110.singleDetail.step.equals("01")) {
							// 第一步，验证码申请
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = "已提交";

							tmpRetDetail.transState = PaymentState.SUCCESS;
							tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
							tmpRetDetail.payInfoCode = respCode;
							tmpRetDetail.transAmt = p_req9110.singleDetail.payAmount;
						} else if (p_req9110.singleDetail.step.equals("02")) {
							// 第二步，首次绑卡支付
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = respMap.get("returnMessage");

							tmpRetDetail.transState = respCode;
							tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
							tmpRetDetail.payInfoCode = respCode;
							tmpRetDetail.transAmt = p_req9110.singleDetail.payAmount;
						} else {
							// 第三步，协议支付
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = respMap.get("returnMessage");

							tmpRetDetail.transState = respCode;
							tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
							tmpRetDetail.payInfoCode = respCode;
							tmpRetDetail.transAmt = p_req9110.singleDetail.payAmount;
						}
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = "验证签名失败!";
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = respMap.get("returnMessage");
				}
			} else if (tmpStrRet[0].equals(FailCode.E9999) || tmpStrRet[0].equals(FailCode.E9981)) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = tmpStrRet[1];

				if (p_req9110.singleDetail.step.equals("01")) {
					tmpRetDetail.transState = PaymentState.FAIL;
				} else {
					tmpRetDetail.transState = PaymentState.FAIL_Payment;
				}

				tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
				tmpRetDetail.payInfoCode = tmpStrRet[0];
				tmpRetDetail.transAmt = p_req9110.singleDetail.payAmount;
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.getMessage();
			
			WriteBankLogLn(e);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**
	 * 订单查询(单笔)
	 */
	public RetAtsSingle d_9146_QrySMSRec(ReqQrySingle p_req9146) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9146.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9146.recAct, "smsRec");
			if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)) {
				tmpRetDetail.respCode = "0";

				if (actItem == null) {
					tmpRetDetail.respInfo = "未找到账号" + p_req9146.recAct + "对应的商户配置信息";
				} else {
					tmpRetDetail.respInfo = "账号" + p_req9146.recAct + "对应的证书文件不存在";
				}

				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.reqSeqID = p_req9146.askNumber;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				tmpRetDetail.transAmt = p_req9146.payAmount;

				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}

			// 签名数据
			HashMap<String, String> signMap = new HashMap<String, String>();

			signMap.put("charset", "00");
			signMap.put("version", "1.0");
			signMap.put("signType", "RSA");
			signMap.put("service", "OrderSearch");
			signMap.put("merchantId", actItem.merchantId);

			// 商户请求号
			signMap.put("requestId", p_req9146.askNumber);

			// 商户订单号
			signMap.put("orderId", p_req9146.askNumber);

			// 获取HTTP post请求数据
			String reqStr = getHttpPostStr(signMap, actItem);

			// 发送邦付宝并获取返回
			String tmpStrRet[] = sendQuickPay(reqStr);

			// 解析邦付宝返回
			if (tmpStrRet[0].length() == 0) {
				Map<String, String> respMap = getRet(tmpStrRet[1].replace("\"", ""));

				String respCode = respMap.get("returnCode");

				if (respCode.equals("000000")) {
					// 服务器签名
					String respSign = respMap.get("serverSign");
					byte[] respSignBytes = hexStringToBytes(respSign);

					// 服务器证书
					String serverCert = respMap.get("serverCert");
					PublicKey pubKey = getPublicKey(serverCert);

					// 验签原始串
					String respVerifyStr = getVerifyStr(tmpStrRet[1]);

					// 验签
					boolean verifyResult = SignVerifyHelper.verifySign(respVerifyStr.getBytes(getCharset()), respSignBytes, pubKey, "SHA1withRSA");

					// 验签处理
					if (verifyResult == true) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = respMap.get("returnMessage");

						tmpRetDetail.transState = respCode + "+" + respMap.get("status");
						tmpRetDetail.reqSeqID = p_req9146.askNumber;
						tmpRetDetail.payInfoCode = respCode;
						tmpRetDetail.transAmt = StringHelper.amountDivide100(respMap.get("totalAmount"));
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = "验证签名失败!";
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = respMap.get("returnMessage");
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.getMessage();

			WriteBankLogLn(e);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
}
